#!/usr/bin/env python
# -*- coding:utf-8 -*-

import datetime
import math
import json

from sqlalchemy import or_
from datetime import datetime

from app import db
from models.article import Article
from utils import commons
from utils.response_code import RET, error_map_EN
from utils.loggings import loggings
from models import BaseModel
from models import db


class ArticleController(Article,BaseModel):

    # add
    @classmethod
    def add(cls, **kwargs):
        from utils.generate_id import GenerateID
        article_id = GenerateID.create_random_id()
        
        try:
            model = Article(
                article_id=article_id,
                publisher_id=kwargs.get('publisher_id'),
                title=kwargs.get('title'),
                content=kwargs.get('content'),
                hits=kwargs.get('hits'),
                review_status=kwargs.get('review_status'),
                pic_url=kwargs.get('pic_url'),
                publish_time=kwargs.get('publish_time'),
                is_recommend=kwargs.get('is_recommend'),
                create_time=kwargs.get('create_time'),
                update_time=kwargs.get('update_time'),
                
            )
            db.session.add(model)
            db.session.commit()
            results = {
                'add_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'article_id': model.article_id,
                
            }
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}
            
        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

    # get
    @classmethod
    def get(cls, **kwargs):
        try:
            filter_list = []
            if kwargs.get('article_id'):
                filter_list.append(cls.article_id == kwargs['article_id'])
            if kwargs.get('is_delete') is not None:
                filter_list.append(cls.is_delete == kwargs.get('is_delete'))
            if kwargs.get('publisher_id') is not None:
                filter_list.append(cls.publisher_id == kwargs.get('publisher_id'))
            if kwargs.get('title'):
                filter_list.append(cls.title == kwargs.get('title'))
            if kwargs.get('content'):
                filter_list.append(cls.content == kwargs.get('content'))
            if kwargs.get('hits') is not None:
                filter_list.append(cls.hits == kwargs.get('hits'))
            if kwargs.get('review_status') is not None:
                filter_list.append(cls.review_status == kwargs.get('review_status'))
            if kwargs.get('pic_url'):
                filter_list.append(cls.pic_url == kwargs.get('pic_url'))
            if kwargs.get('publish_time'):
                filter_list.append(cls.publish_time == kwargs.get('publish_time'))
            if kwargs.get('is_recommend') is not None:
                filter_list.append(cls.is_recommend == kwargs.get('is_recommend'))

            page = int(kwargs.get('Page', 1))
            size = int(kwargs.get('Size', 10))
            
            article_info = db.session.query(cls).filter(*filter_list)
            
            count = article_info.count()
            if count == 0:
                return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': []}
            
            pages = math.ceil(count / size)
            article_info = article_info.limit(size).offset((page - 1) * size).all()

            results = []
            for article in article_info:
                article_dict = {
                    'article_id': article.article_id,
                    'publisher_id': article.publisher_id,
                    'title': article.title,
                    'content': article.content,
                    'hits': article.hits,
                    'review_status': article.review_status,
                    'pic_url': article.pic_url,
                    'publish_time': article.publish_time.strftime("%Y-%m-%d %H:%M:%S") if article.publish_time else None,
                    'is_recommend': article.is_recommend,
                    'is_delete': article.is_delete
                }
                results.append(article_dict)

            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'totalCount': count, 'totalPage': pages, 'data': results}
            
        except Exception as e:
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()

    # delete
    @classmethod
    def delete(cls, **kwargs):
        try:
            filter_list = [cls.is_delete == 0]
            if kwargs.get('article_id'):
                primary_key_list = []
                for primary_key in str(kwargs.get('article_id')).replace(' ', '').split(','):
                    primary_key_list.append(cls.article_id == primary_key)
                filter_list.append(or_(*primary_key_list))
                
            else:
                if kwargs.get('publisher_id') is not None:
                    filter_list.append(cls.publisher_id == kwargs.get('publisher_id'))
                if kwargs.get('title'):
                    filter_list.append(cls.title == kwargs.get('title'))
                if kwargs.get('content'):
                    filter_list.append(cls.content == kwargs.get('content'))
                if kwargs.get('hits') is not None:
                    filter_list.append(cls.hits == kwargs.get('hits'))
                if kwargs.get('review_status') is not None:
                    filter_list.append(cls.review_status == kwargs.get('review_status'))
                if kwargs.get('pic_url'):
                    filter_list.append(cls.pic_url == kwargs.get('pic_url'))
                if kwargs.get('publish_time'):
                    filter_list.append(cls.publish_time == kwargs.get('publish_time'))
                if kwargs.get('is_recommend') is not None:
                    filter_list.append(cls.is_recommend == kwargs.get('is_recommend'))
                if kwargs.get('create_time'):
                    filter_list.append(cls.create_time == kwargs.get('create_time'))
                if kwargs.get('update_time'):
                    filter_list.append(cls.update_time == kwargs.get('update_time'))
                
            res = db.session.query(cls).filter(*filter_list).with_for_update()

            results = {
                'delete_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
                'article_id': []
            }
            for query_model in res.all():
                results['article_id'].append(query_model.article_id)

            res.update({'is_delete': 1})
            db.session.commit()

            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}

        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()
    
    # update
    @classmethod
    def update(cls, **kwargs):
        try:
            article_id = kwargs.get('article_id')
            article = Article.query.filter_by(article_id=article_id).first()
            
            if not article:
                return {'code': 404, 'message': '文章不存在', 'data': None}
            
            for key, value in kwargs.items():
                if hasattr(article, key) and value is not None:
                    setattr(article, key, value)
            
            article.update_time = datetime.now()
            db.session.commit()
            
            return {
                'code': 200,
                'message': 'success',
                'data': {
                    'article_id': article.article_id,
                    'title': article.title,
                    'content': article.content,
                    'publisher_id': article.publisher_id,
                    'hits': article.hits,
                    'pic_url': article.pic_url,
                    'review_status': article.review_status,
                    'is_recommend': article.is_recommend,
                    'is_delete': article.is_delete,
                    'publish_time': article.publish_time.strftime('%Y-%m-%d %H:%M:%S') if article.publish_time else None,
                    'create_time': article.create_time.strftime('%Y-%m-%d %H:%M:%S') if article.create_time else None,
                    'update_time': article.update_time.strftime('%Y-%m-%d %H:%M:%S')
                }
            }
            
        except Exception as e:
            db.session.rollback()
            return {'code': 500, 'message': str(e), 'data': None}

    # batch add
    @classmethod
    def add_list(cls, **kwargs):
        param_list = kwargs.get('ArticleList')
        model_list = []
        for param_dict in param_list:
            from utils.generate_id import GenerateID
            article_id = GenerateID.create_random_id()
            
            model = Article(
                article_id=article_id,
                publisher_id=param_dict.get('publisher_id'),
                title=param_dict.get('title'),
                content=param_dict.get('content'),
                hits=param_dict.get('hits'),
                review_status=param_dict.get('review_status'),
                pic_url=param_dict.get('pic_url'),
                publish_time=param_dict.get('publish_time'),
                is_recommend=param_dict.get('is_recommend'),
                create_time=param_dict.get('create_time'),
                update_time=param_dict.get('update_time'),
                
            )
            model_list.append(model)
        
        try:
            db.session.add_all(model_list)
            db.session.commit()
            results = {
                'added_records': [],
                'add_time': datetime.now().strftime("%Y-%m-%d %H:%M:%S")
            }
            for model in model_list:
                added_record = {}
                added_record['article_id'] = model.article_id
                
                results['added_records'].append(added_record)
                
            return {'code': RET.OK, 'message': error_map_EN[RET.OK], 'data': results}
            
        except Exception as e:
            db.session.rollback()
            loggings.exception(1, e)
            return {'code': RET.DBERR, 'message': error_map_EN[RET.DBERR], 'data': {'error': str(e)}}
        finally:
            db.session.close()
